package com.greensecurity.sim.util;

import com.greensecurity.sim.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.math.BigDecimal;
import java.math.RoundingMode;

@Slf4j
public class ComputeUtil {
    private static double rValue;
    public static void greenCompute(User user){
        for (Green green : user.getGreen()){
            Grid grid = green.getGrid();
            Manager manager = green.getManager();
            int R = computeGrade(grid,manager);
            green.setWaringGrade(R);
            green.setRValue(rValue);
            log.info("计算R的总值:"+rValue);
        }
    }
    private static int computeGrade(Grid grid,Manager manager){
        double p = computeP(grid,manager);
        log.info("P的值是:"+p);
        double s = computeS(grid,manager);
        log.info("S的值是:"+s);
        double r = computeR(grid,manager);
        log.info("r的值是:"+r);
        double R = mul(mul(mul(p,0.458),mul(s,0.416)),mul(r,0.126));
        R = Math.pow(R,(1.0/3));//开3根号
        BigDecimal bd = new BigDecimal(R);
        R =  bd.setScale(3, RoundingMode.HALF_UP).doubleValue();
        rValue = R;
        log.info("R的值是:"+R);
        if (R>=0.235&&R<=0.296){
            //无警报
            return 4;
        }
        if (R>=0.297&&R<=0.470){
            //1级警报
            return 3;
        }
        if (R>=0.471&&R<=0.705){
            //二级警报
            return 2;
        }
        if (R>=0.706&&R<=0.940){
            //三级警报
            return 1;
        }
        if (R>=0.941&&R<=1.175){
            //四级警报
            return 0;
        }

        return 6;
    }


    private static double computeR(Grid grid,Manager manager){
        double r,r1,r2;
        r1 = add(mul(manager.getR11(),0.333),mul(manager.getR12(),0.667));
        r2 = add(add(add(mul(manager.getR21(),0.158),mul(grid.getR22(),0.069)),mul(grid.getR23(),0.229)),mul(manager.getR24(),0.545));
        return add(mul(r1,0.667),mul(r2,0.333));
    }

    private static double computeS(Grid grid,Manager manager){
        double s1=grid.getS11() ,s2;
        s2 = add(add(mul(grid.getS21(),0.493),mul(grid.getS25(),0.311)),mul(grid.getS26(),0.196));
        return add(mul(s1,0.333),mul(s2,0.667));
    }



    private static double computeP(Grid grid,Manager manager){
        double p1 ,p2;
        p1 = add(add(add(mul(manager.getP11(),0.32),mul(manager.getP12(),0.081)),mul(manager.getP13(),0.077)),mul(manager.getP14(),0.523));
        p2 = mul(mul(mul(mul(mul(mul(mul(mul(mul(grid.getP21(),0.042),mul(grid.getP22(),0.029)),mul(manager.getP23(),0.085)),mul(manager.getP24(),0.07))
                ,mul(manager.getP25(),0.136)),mul(manager.getP26(),0.033)),mul(manager.getP27(),0.267)),mul(manager.getP28(),0.08))
                ,mul(manager.getP29(),0.259));


        p2 = Math.pow(p2,(1.0/9));//开9次方


        return add(mul(p1,0.5),mul(p2,0.5));
    };

    public static double mul(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        double data = b1.multiply(b2).doubleValue();
        return data;
    }
    public static double add(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }
    @Test
    public void test(){
//        BigDecimal bd = new BigDecimal(0.124556487);
//        double p1 = bd.setScale(3, RoundingMode.HALF_UP  ).doubleValue();
//        double p2 = 512^(1/9);
//        double p3 = Math.pow(512.0154,(1.0/9));//第二个参数一定要用double类型
//        log.info("计算技术数据:"+String.valueOf(p3));

        Grid grid = new Grid();
        Manager manager = new Manager();

        manager.setP11(3);
        manager.setP12(2);
        manager.setP13(3);
        manager.setP14(5);
        grid.setP21(1);
        grid.setP22(1);
        manager.setP23(1);
        manager.setP24(1);
        manager.setP25(1);
        manager.setP26(1);
        manager.setP27(2);
        manager.setP28(3);
        manager.setP29(1);
        grid.setS11(3);
        grid.setS21(4);
        grid.setS25(1);
        grid.setS26(1);
        manager.setR11(1);
        manager.setR12(1);
        manager.setR21(1);
        grid.setR22(1);
        grid.setR23(1);
        manager.setR24(1);
        log.info("最终计算："+computeGrade(grid,manager));
    }
}
